package com.project.web.admin.service.core.impl;

import com.project.mapper.core.StdCodeMapper;
import com.project.mapper.core.StdCodeTypeMapper;
import com.project.model.core.StdCode;
import com.project.model.core.StdCodeType;
import com.project.web.admin.service.common.impl.BaseServiceImpl;
import com.project.web.admin.service.core.StdCodeService;
import org.yun.common.utils.redis.RedisClient;
import org.yun.common.utils.redis.RedisConsts;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 标准编码service实现
 */
@Service(value = "stdCodeServiceImpl")
public class StdCodeServiceImpl extends BaseServiceImpl<StdCode, Long> implements StdCodeService {

    private static final long serialVersionUID = -5135800135942173359L;

    @Autowired
    private StdCodeMapper stdCodeMapper;

    @Autowired
    private StdCodeTypeMapper stdCodeTypeMapper;

    @Resource(name = "redisClient")
    private RedisClient redisClient;


    /**
     * 获取codeType的codeList
     *
     * @param stdCodeType    codeType对象
     * @param isShowDisabled 是否显示不可用的
     * @return
     */
    public List<StdCode> findList(StdCodeType stdCodeType, boolean isShowDisabled) {

        if (stdCodeType == null) {
            return new ArrayList<StdCode>();
        }

        List<StdCode> list = null;

        //先从缓存中获取
        Object redisObject = redisClient.get(RedisConsts.SYSTEM_STDCODE_LIST + stdCodeType.getCodeType() + ":" + isShowDisabled);

        if (redisObject != null) {
            return (List<StdCode>) redisObject;
        }

        list = stdCodeMapper.selectByCodeType(stdCodeType.getId());

        //遍历可用的stdCode，放入result的List对象
        List<StdCode> result = new ArrayList<StdCode>();
        if (list != null) {
            for (StdCode stdCode : list) {
                if (stdCode.getIsEnabled()) {
                    result.add(stdCode);
                }
            }
        }

        //放入缓存
        redisClient.set(RedisConsts.SYSTEM_STDCODE_LIST + stdCodeType.getCodeType() + ":false", result);
        redisClient.set(RedisConsts.SYSTEM_STDCODE_LIST + stdCodeType.getCodeType() + ":true", list);

        return isShowDisabled ? list : result;
    }

    /**
     * 查询code的List
     *
     * @param codeType
     * @param isShowDisabled 是否显示不可用的
     * @return
     */
    public List<StdCode> findList(String codeType, boolean isShowDisabled) {
        return this.findList(stdCodeTypeMapper.getByCodeType(codeType), isShowDisabled);
    }

    /**
     * 查询code的List，包括不可用的
     *
     * @param codeType
     * @return
     */
    public List<StdCode> findList(String codeType) {
        return this.findList(codeType, true);
    }

    /**
     * 获取codeType的map
     *
     * @param codeType
     * @param isShowDisabled 是否显示不可用的
     * @return
     */
    public Map<String, String> getMap(String codeType, boolean isShowDisabled) {

        if (StringUtils.isEmpty(codeType)) {
            return new LinkedHashMap<String, String>();
        }

        //先从缓存中获取
        Map<String, String> map = (LinkedHashMap<String, String>) redisClient.get(RedisConsts.SYSTEM_STDCODE_MAP + codeType + ":" + isShowDisabled);

        if (MapUtils.isNotEmpty(map)) {
            return map;
        }

        List<StdCode> list = this.findList(codeType, isShowDisabled);
        map = new LinkedHashMap<String, String>();

        for (StdCode stdCode : list) {
            map.put(stdCode.getCode(), stdCode.getCodeName());
        }

        //放入缓存
        redisClient.set(RedisConsts.SYSTEM_STDCODE_MAP + codeType + ":" + isShowDisabled, map);
        return map;
    }

    /**
     * 查询code的map，包括不可用的
     *
     * @param codeType
     * @return
     */
    public Map<String, String> getMap(String codeType) {
        return getMap(codeType, true);
    }

    /**
     * 根据多个id查询标准编码
     *
     * @param list
     * @return
     */
    @Override
    public List<StdCode> findList(List<Long> list) {
        return stdCodeMapper.findList(list);
    }

    @Override
    public StdCode update(StdCode entity) {
        StdCodeType stdCodeType = stdCodeTypeMapper.getById(entity.getCodeType());
        deleteKeyFromRedis(stdCodeType.getCodeType());
        return super.update(entity);
    }

    @Override
    public StdCode save(StdCode entity) {
        StdCodeType stdCodeType = stdCodeTypeMapper.getById(entity.getCodeType());
        deleteKeyFromRedis(stdCodeType.getCodeType());
        return super.save(entity);
    }

    @Override
    public int delete(Long id) {
        StdCode entity = stdCodeMapper.getById(id);
        StdCodeType stdCodeType = stdCodeTypeMapper.getById(entity.getCodeType());
        deleteKeyFromRedis(stdCodeType.getCodeType());
        return super.delete(id);
    }

    /**
     * 从缓存中删除标准编码的key
     *
     * @param codeType
     */
    private void deleteKeyFromRedis(String codeType) {
        redisClient.del(RedisConsts.SYSTEM_STDCODE_LIST + codeType + ":true");
        redisClient.del(RedisConsts.SYSTEM_STDCODE_LIST + codeType + ":false");
        redisClient.del(RedisConsts.SYSTEM_STDCODE_MAP + codeType + ":true");
        redisClient.del(RedisConsts.SYSTEM_STDCODE_MAP + codeType + ":false");
    }
}
